#include "preHeader.h"
#include "Session/ClientSession.h"
#include "Session/ClientSessionHandler.h"
#include "Session/GameServerSession.h"
#include "Session/CenterSession.h"
#include "Session/ClientMgr.h"
#include "GateServer.h"

int ClientSessionHandler::HandlePing(ClientSession *pSession, INetPacket &pck)
{
	NetPacket resp(SMSG_PONG);
	pSession->PushSendPacket(resp);
	return SessionHandleSuccess;
}

int ClientSessionHandler::HandleMmorpgLogin(ClientSession *pSession, INetPacket &pck)
{
	uint32 acct;
	std::string token;
	pck >> pSession->m_lang >> pSession->m_channel
		>> pSession->m_platform >> pSession->m_logicGsID;
	pck >> acct >> token;

	auto VerifyAccountValidityCallback = [=, sn = pSession->sn()](INetStream& pck)->GErrorCode {
		int32 errCode;
		std::string_view errMsg;
		pck >> errCode >> errMsg;
		auto pClient = sClientMgr.GetClient(sn);
		if (pClient == NULL || pClient->IsAccountOK()) {
			WLOG("verify client`%u` account`%u` code 1.", pSession->sn(), acct);
			return CommonSuccess;
		}

		NetPacket resp(SMSG_MMORPG_LOGIN_RESP);
		resp << acct << errCode << errMsg;
		pClient->PushSendPacket(resp);
		if (errCode != 0) {
			WLOG("verify client`%u` account`%u` code 2.", pSession->sn(), acct);
			return CommonSuccess;
		}

		if (!sGameServerSession.IsReady()) {
			sClientMgr.KickClient(pClient, LOGIN_ERROR_GATE_SERVER_OFFLINE);
			WLOG("verify client`%u` account`%u` code 3.", pSession->sn(), acct);
			return CommonInternalError;
		}

		NetPacket notify(CGG_ACCOUNT_LOGIN_SUCC);
		notify << pClient->logicGsID() << pClient->sn() << acct;
		sGameServerSession.PushSendPacket(notify);

		pClient->SetAccountOK(acct);
		NLOG("verify client`%u` account`%u` successfully.", pSession->sn(), acct);

		return CommonSuccess;
	};

	NetPacket rpcReqPck(CCT_VERIFY_ACCOUNT_VALIDITY);
	rpcReqPck << acct << token;
	sCenterSession.RPCInvoke(rpcReqPck, [=](INetStream& pck, int32 err, bool) {
		if (err == RPCErrorNone) {
			VerifyAccountValidityCallback(pck);
		} else {
			WLOG("CenterSession.RPCInvoke(`%u`) HandleMmorpgLogin error[%d].",
				pSession->sn(), err);
		}
	}, &sGateServer, DEF_S2S_RPC_TIMEOUT);
	NLOG("start verify client`%u` account`%u` ...", pSession->sn(), acct);

	return SessionHandleSuccess;
}

int ClientSessionHandler::HandleMmorpgLogout(ClientSession *pSession, INetPacket &pck)
{
	pSession->PushSendPacket(NetPacket(SMSG_MMORPG_LOGOUT_RESP));
	sClientMgr.SendLogoutAccount2GameServer(pSession);
	sClientMgr.KickClient(pSession, CommonSuccess);
	NLOG("logout client`%u` account`%u`.", pSession->sn(), pSession->getAcctId());
	return SessionHandleSuccess;
}
